package com.blueheart.Test.util;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.function.Supplier;

public class GenericTest {

    public static void main(String[] args) {
        String[] words = {"Mary","had","a","little","lamb"};
        Pair<String> minmax = ArrayAlg.minmax(words);
        if(minmax instanceof Pair){
            System.out.println(true);
        }
        if(minmax.getClass() == Pair.class){
            System.out.println(true);
        }
        System.out.println(minmax.getFirst());
        System.out.println(minmax.getSecond());

        String middle = ArrayAlg.getMiddle("John", "Q.", "Public");
        System.out.println(middle);

        Number middle1 = ArrayAlg.getMiddle(3.14, 1792, 0);
        System.out.println(middle1);
    }


}

class ArrayAlg {
    public static <T extends Comparable> Pair<T> minmax(T[] a){
        if(a == null || a.length == 0 ) return null;
        T min = a[0];
        T max = a[0];
        for(int i = 1; i < a.length; i++){
            if(min.compareTo(a[i])>0) min = a[i];
            if(max.compareTo(a[i])<0) max = a[i];
        }
        return new Pair<>(min,max);
    }

    //泛型方法
    public static <T> T getMiddle(T... a){
        return a[a.length/2];
    }

    //参数类限定符
    public static <T extends Comparable & Serializable> T min(T[] a){
        if(a==null || a.length==0) return null;
        T smallest = a[0];
        for(int i = 1; i < a.length; i++){
            if(smallest.compareTo(a[i])>0) smallest = a[i];
        }
        return smallest;
    }

}

//泛型类
class Pair<T> {

    private T first;
    private T second;

    public static <T> Pair<T> makePair(Supplier<T> constr){
        return new Pair<>(constr.get(),constr.get());
    }

    public static <T> Pair<T> makePair(Class<T> cl){
        try {
            return new Pair<>(cl.getConstructor().newInstance(),cl.getConstructor().newInstance());
        } catch (Exception e){
            return null;
        }
    }

    public Pair(){
        this.first = null;
        this.second = null;
    }

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public void setFirst(T first) {
        this.first = first;
    }

    public T getSecond() {
        return second;
    }

    public void setSecond(T second) {
        this.second = second;
    }
}
